package com.thirdnf.calendar;


import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;


/**
 * @author Joshua Gerth - jgerth@thirdnf.com
 */
public class DayOfMonth extends JPanel implements MouseListener {

    public enum State { Disabled, Standard, Weekend, Today }

    private static int height = 25;
    private static int width = 25;

    private final List<ActionListener> _actionListeners;

    private final Border OverBorder = BorderFactory.createLineBorder(Color.black);
    private final Border OutBorder = BorderFactory.createEmptyBorder(1, 1, 1, 1);
    private final Color BackgroundNormal = Color.lightGray;
    private final Color BackgroundClicked = Color.darkGray;

    private Boolean _enabled;

    private JLabel _label;

    private int _value;
    private boolean _selected;

    public DayOfMonth() {

        setSize(width, height);
        setMinimumSize(new Dimension(width, height));
        setPreferredSize(new Dimension(width, height));

        _actionListeners = new ArrayList<ActionListener>();
        setBackground(BackgroundNormal);

        setBorder(OutBorder);

        addMouseListener(this);

        _label = new JLabel("x");
        _label.setHorizontalAlignment(SwingConstants.CENTER);

        add(_label);

        setOpaque(false);

        _enabled = true;
    }


    public void setValue(int value) {

        _value = value;
        _label.setText(Integer.toString(value));
    }


    public void setState(@NotNull State state) {

        switch (state) {

            case Disabled:
                _enabled = false;
                _label.setForeground(Color.lightGray);
                setOpaque(false);
                break;
            case Standard:
                _enabled = true;
                _label.setForeground(Color.black);
                break;
            case Weekend:
                _enabled = true;
                _label.setForeground(Color.blue);
                break;
            case Today:
                _enabled = true;
                _label.setForeground(Color.red);
                break;
            default:
                throw new RuntimeException("Don't know about state: " + state);
        }
    }


    @Override
    public boolean isEnabled()
    {
        return _enabled;
    }


    public void setSelected(boolean selected) {

        if (selected) {
            setOpaque(true);
        } else {
            setOpaque(false);
        }

        _selected = selected;

        repaint();
    }


    public int getValue() {
        return _value;
    }


    public void addActionListener(ActionListener l) {

        _actionListeners.add(l);
    }


    @Override
    public void mouseClicked(MouseEvent e) {

        if (!_enabled) {
            return;
        }

        for (ActionListener listener : _actionListeners) {
            listener.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "click"));
        }
    }


    @Override
    public void mousePressed(MouseEvent e) {

        if (!_enabled) {
            return;
        }

        setBackground(BackgroundClicked);
        setOpaque(true);
    }


    @Override
    public void mouseReleased(MouseEvent e) {

        setBackground(BackgroundNormal);

        if (! _selected) {
            setOpaque(false);
        }

        // For some reason, if the window closes while they are still over this the damn border is not
        //  being removed, so, for now, we just have to remove it as soon as they click ... which
        //  still won't cover all the cases, but it will cover enough for now.
        setBorder(OutBorder);
    }


    @Override
    public void mouseEntered(MouseEvent e) {

        if (!_enabled) {
            return;
        }

        setBorder(OverBorder);
    }


    @Override
    public void mouseExited(MouseEvent e) {
        // Always do this, just in case we set it to disabled before we existed.
        setBorder(OutBorder);
    }
}
